#include "Instruction.h"

using namespace COOLangage;
#include <cstdio>

COOLangage::Instruction::Instruction() { }

COOLangage::Instruction::~Instruction() throw(){ }

VisitorResult COOLangage::Instruction::visit(VisitorInstruction *visitor) {
	return visitor->visitInstruction(this);
}

// -----------------------------------------------------------------------------------------------

COOLangage::Bloc::Bloc(Instruction *corps) {
	this->corps = corps;
}

COOLangage::Bloc::~Bloc() throw(){
	if(this->corps != NULL)
		delete this->corps;
}

Instruction* COOLangage::Bloc::getCorps() const {
	return corps;
}

VisitorResult COOLangage::Bloc::visit(VisitorInstruction *visitor) {
	return visitor->visitBloc(this);
}

// -----------------------------------------------------------------------------------------------
COOLangage::Sequence::Sequence() { 
}

COOLangage::Sequence::~Sequence() throw() {
	while(seq.size()>0) {
		Instruction *i = seq.back();
		seq.pop_back();
		delete i;
	}
}

int COOLangage::Sequence::size() const {
	return seq.size();
}

std::vector<Instruction*> COOLangage::Sequence::getSequence() const {
	return seq;
}

VisitorResult COOLangage::Sequence::visit(VisitorInstruction *visitor) {
	return visitor->visitSequence(this);
}

// -----------------------------------------------------------------------------------------------


COOLangage::Conditionnelle::Conditionnelle(Expression *cond, 
		Instruction *cons, Instruction * alt)
{
	this->condition = cond;
	this->consequence = cons;
	this->alternant = alt;
}

COOLangage::Conditionnelle::~Conditionnelle() throw(){
	if(condition != NULL)
		delete condition;
	if(consequence != NULL)
		delete consequence;
	if(alternant != NULL)
		delete alternant;
}

Expression* COOLangage::Conditionnelle::getCondition() const {
	return condition;
}

Instruction* COOLangage::Conditionnelle::getConsequence() const {
	return consequence;
}

Instruction* COOLangage::Conditionnelle::getAlternant() const {
	return alternant;
}

VisitorResult COOLangage::Conditionnelle::visit(VisitorInstruction *visitor) {
	return visitor->visitConditionnelle(this);
}

// -----------------------------------------------------------------------------------------------

COOLangage::ExprInstruction::ExprInstruction(Expression *expr) {
	this->expr = expr;
}

COOLangage::ExprInstruction::~ExprInstruction() throw(){
	if(expr != NULL)
		delete expr;
}

Expression* COOLangage::ExprInstruction::getExpression() const {
	return expr;
}

VisitorResult COOLangage::ExprInstruction::visit(VisitorInstruction *visitor) {
	return visitor->visitExprInstruction(this);
}

// -----------------------------------------------------------------------------------------------

COOLangage::InstructionReturn::InstructionReturn(Expression *expr) {
	this->expr = expr;
}

COOLangage::InstructionReturn::~InstructionReturn() throw(){
	if(expr != NULL)
		delete expr;
}

Expression* COOLangage::InstructionReturn::getExpression() const {
	return expr;
}

VisitorResult COOLangage::InstructionReturn::visit(VisitorInstruction *visitor) {
	return visitor->visitInstructionReturn(this);
}

// -----------------------------------------------------------------------------------------------

COOLangage::Boucle::Boucle(Expression* cond, Instruction* corps) {
	this->condition = cond;
	this->corps = corps;
}

COOLangage::Boucle::~Boucle() throw(){
	if(condition != NULL)
		delete condition;
	if(corps != NULL)
		delete corps;
}
Expression* COOLangage::Boucle::getCondition() const {
	return condition ;
}
Instruction* COOLangage::Boucle::getCorps() const  {
	return corps ;
}
VisitorResult COOLangage::Boucle::visit(VisitorInstruction *visitor) {
	return visitor->visitBoucle(this);
}

// -----------------------------------------------------------------------------------------------
COOLangage::Affectation::Affectation(Variable *v, Expression *e) {
	this->variable = v;
	this->valeur = e;
}

COOLangage::Affectation::~Affectation() throw(){
	if(variable != NULL)
		delete variable;
	if(valeur != NULL)
		delete valeur;
}

Variable* COOLangage::Affectation::getVariable() const {
	return variable;
}

Expression* COOLangage::Affectation::getValeur() const {
	return valeur;
}

VisitorResult COOLangage::Affectation::visit(VisitorInstruction *visitor) {
	return visitor->visitAffectation(this);
}

// -----------------------------------------------------------------------------------------------

COOLangage::DeclarationVariable::DeclarationVariable(Type *type, Variable *variable) {
	this->type =type;
	this->variable = variable;
}

COOLangage::DeclarationVariable::~DeclarationVariable() throw() {
	if(type != NULL)
		delete type;
	if(variable != NULL)
		delete variable;
}

Type* COOLangage::DeclarationVariable::getType() const {
	return this->type;
}

Variable* COOLangage::DeclarationVariable::getVariable() const {
	return this-> variable;
}

VisitorResult COOLangage::DeclarationVariable::visit(VisitorInstruction *visitor) {
	return visitor->visitDeclarationVariable(this);
}


// -----------------------------------------------------------------------------------------------
